import { CSMesh, KeepSizeObject3D } from '@amcax/base';
import { calculatePoint } from '@app-cad/common/utils';
import { ctx2 } from '@app-cad/module';
import {
  BufferGeometry,
  DoubleSide,
  MeshBasicMaterial,
  Object3D,
  Vector3,
} from 'three-legacy';
// -------------------
type ArrowAttrs = {
  vec?: Vector3;
  arrowEnd?: Vector3;
  center?: Vector3;
};
export class Arrow {
  vec: Vector3;
  arrowEnd: Vector3;
  center: Vector3;
  arrowMesh: CSMesh;
  keepSizeGroup: KeepSizeObject3D;
  scene: Object3D;
  position: Vector3;
  constructor(attrs: ArrowAttrs) {
    this.createArrow(attrs);
    this.keepSizeGroup = new KeepSizeObject3D(ctx2.viewer.sceneSetup.camera);
    this.keepSizeGroup.renderOrder = 1000;
  }
  // 创建箭头
  getArrowPoint({ vec, arrowEnd, center }: ArrowAttrs) {
    arrowEnd && (this.position = arrowEnd);
    // 设置箭头头部参数
    const arrowHeadLength = 1.5; // 箭头头部的长度
    // 计算箭头方向和基准点
    const arrowDirection = new Vector3()
      .subVectors(arrowEnd, center) // 将该向量设置为 箭头起点 - 箭头的顶点
      .normalize(); // 将该向量转换为单位向量（unit vector）， 也就是说，将该向量的方向设置为和原向量相同，但是其长度（length）为1。
    //旋转轴
    const axis = new Vector3()
      .crossVectors(vec, ctx2.viewer.sceneSetup.camera.up)
      .normalize();
    const sign = Math.sign(vec.dot(arrowDirection));
    // console.log('sign', sign);
    const startP = calculatePoint(
      vec,
      (sign * -arrowHeadLength) / 1.7,
      new Vector3(0, 0, 0),
    );
    const startP2 = calculatePoint(
      vec,
      (sign * -arrowHeadLength) / 3,
      new Vector3(0, 0, 0),
    );
    const vertex3 = calculatePoint(vec, (sign * -arrowHeadLength) / 2, startP);
    // vec 向量旋转90deg
    const vec2 = vec.clone().applyAxisAngle(axis, Math.PI / 2);
    const vertex1 = calculatePoint(vec2, arrowHeadLength / 1.5, startP);
    const vertex2 = calculatePoint(vec2, -arrowHeadLength / 1.5, startP);

    const r1 = calculatePoint(vec2, arrowHeadLength / 3, startP);
    const r2 = calculatePoint(vec2, -arrowHeadLength / 3, startP);
    const r3 = calculatePoint(vec2, arrowHeadLength / 3, startP2);
    const r4 = calculatePoint(vec2, -arrowHeadLength / 3, startP2);
    return [
      vertex3,
      vertex1,
      r1,
      r1,
      r3,
      r2,
      r3,
      r4,
      r2,
      r2,
      vertex2,
      vertex3,
      vertex3,
      r1,
      r2,
    ];
  }
  // 创建箭头
  createArrow(attrs: ArrowAttrs) {
    const vertices = this.getArrowPoint(attrs);
    const geometry = new BufferGeometry();
    geometry.setFromPoints(vertices);
    const material = new MeshBasicMaterial({
      side: DoubleSide,
      depthTest: false, // 不进行深度测试
      color: '#00ff00',
    });
    this.arrowMesh = new CSMesh({
      geometry,
      material,
      modelDxid: 'divMesh',
    });
    this.arrowMesh.setRenderOrder(1000);
    this.arrowMesh.visible = true;
  }
  // 更新箭头
  update(attrs: ArrowAttrs) {
    const vertices = this.getArrowPoint(attrs);
    this.arrowMesh.geometry.setFromPoints(vertices);
    this.setPosition();
  }
  // 添加到场景
  addTo(scene) {
    this.scene = scene;
    this.arrowMesh.addTo(this.keepSizeGroup);
    scene.add(this.keepSizeGroup);
    this.setPosition();
  }
  //
  setPosition() {
    if (this.position) {
      this.keepSizeGroup.position.copy(this.position);
    }
  }
  // 销毁
  destroy() {
    this.scene.remove(this.keepSizeGroup);
    this.arrowMesh?.destroy();
    this.keepSizeGroup.clear();
  }
}
